/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.projects.content; import java.io.*; import java.text.MessageFormat; import java.util.*; import org.openide.loaders.XMLDataObject; import org.openide.util.SharedClassObject; import org.openide.util.Utilities; import org.openide.util.io.*; import org.openidex.projects.*; import org.xml.sax.*; /** * * @author mryzl * @version */ public class XMLSupport extends Object { public static final String EMPTY_STRING = ""; // NOI18N public static final String FMT_XML_HEADER = "<?xml version=\"1.0\"?>"; // NOI18N public static final String FMT_OBJECTS_START = "<{0} version=\"1.0\">"; // NOI18N public static final String FMT_OBJECTS_END = "</{0}>"; // NOI18N public static final String ELEMENT_CONTROL_PANEL = "control-panel"; // NOI18N public static final String ELEMENT_MODULES= "modules"; // NOI18N public static final String ELEMENT_LOADERS = "loaders"; // NOI18N /** Creates new XMLSupport */ public XMLSupport() { } public static String encodeToProperXML(String text) { if (text.indexOf ('&') != -1) text = Utilities.replaceString (text, "&", "&"); // must be the first to prevent changes in the &XX; codes // NOI18N if (text.indexOf ('<') != -1) text = Utilities.replaceString (text, "<", "<"); // NOI18N if (text.indexOf ('>') != -1) text = Utilities.replaceString (text, ">", ">"); // NOI18N if (text.indexOf ('\'') != -1) text = Utilities.replaceString (text, "\'", "'"); // NOI18N if (text.indexOf ('\"') != -1) text = Utilities.replaceString (text, "\"", """); // NOI18N if (text.indexOf ('\n') != -1) text = Utilities.replaceString (text, "\n", " "); // NOI18N if (text.indexOf ('\t') != -1) text = Utilities.replaceString (text, "\t", " "); // NOI18N return text; } /** Decodes a value of from the specified String containing textual representation of serialized stream. * @return decoded object * @exception IOException thrown if an error occures during deserializing the object */ public static Object decodeValue (String value) throws IOException { if ((value == null) || (value.length () == 0)) return null; char[] bisChars = value.toCharArray (); byte[] bytes = new byte[bisChars.length]; String singleNum = ""; // NOI18N int count = 0; for (int i = 0; i < bisChars.length; i++) { if (',' == bisChars[i]) { try { bytes[count++] = Byte.parseByte (singleNum); } catch (NumberFormatException e) { if (Boolean.getBoolean ("netbeans.debug.exceptions")) e.printStackTrace (); // NOI18N throw new IOException (); } singleNum = EMPTY_STRING; } else { singleNum += bisChars[i]; } } // add the last byte bytes[count++] = Byte.parseByte (singleNum); ByteArrayInputStream bis = new ByteArrayInputStream (bytes, 0, count); try { ObjectInputStream ois = new NbObjectInputStream (bis); Object ret = ois.readObject (); return ret; } catch (IOException ex) { if (Boolean.getBoolean ("netbeans.debug.exceptions")) ex.printStackTrace (); // NOI18N throw ex; } catch (Exception ex) { if (Boolean.getBoolean ("netbeans.debug.exceptions")) ex.printStackTrace (); // NOI18N throw new FoldingIOException(ex); } } /** Encodes specified value to a String containing textual representation of serialized stream. * @return String containing textual representation of the serialized object */ public static String encodeValue (Object value) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream (); try { ObjectOutputStream oos = new NbObjectOutputStream (bos); oos.writeObject (value); oos.close (); } catch (Exception ex) { if (Boolean.getBoolean ("netbeans.debug.exceptions")) ex.printStackTrace (); // NOI18N throw new FoldingIOException(ex); // problem during serialization } byte[] bosBytes = bos.toByteArray (); StringBuffer sb = new StringBuffer (bosBytes.length); for (int i = 0; i < bosBytes.length; i++) { if (i != bosBytes.length - 1) { sb.append (bosBytes[i]+","); // NOI18N } else { sb.append ("" + bosBytes[i]); // NOI18N } } return sb.toString (); } /** Encode strings to one. Comma will be used as a delimiter. * @param list of strings */ public static String encodeStrings(List list) { Iterator it = list.iterator(); StringBuffer sb = new StringBuffer(); boolean comma = false; for(int i = 0; it.hasNext();) { if (comma) { sb.append(','); } else { comma = true; } sb.append(encodeToProperXML((String)it.next())); } return sb.toString(); } /** Decode strings from one string with comma as a delimiter. * @return list of strings */ public static List decodeStrings(String value) { List list = new LinkedList(); StringTokenizer st = new StringTokenizer(value, ","); // NOI18N while (st.hasMoreTokens()) { list.add(st.nextToken()); } return list; } /** Save given array of objects to the XML file. * @param writer * @param map with classnames and values * @param mainElement main element of the XML */ public static void saveObjects(Writer writer, Map map, String mainElement) { Object[] formatObjs = new Object[] { mainElement }; PrintWriter pw = new PrintWriter(writer); pw.println(FMT_XML_HEADER); pw.println(MessageFormat.format(FMT_OBJECTS_START, formatObjs)); Iterator it = map.keySet().iterator(); while (it.hasNext()) { SharedClassObject sco = (SharedClassObject) it.next(); pw.print(" <object name=\""); // NOI18N pw.print(encodeToProperXML(sco.getClass().getName())); pw.print("\" value=\""); // NOI18N pw.print(map.get(sco)); pw.println("\"/>"); // NOI18N } pw.println(MessageFormat.format(FMT_OBJECTS_END, formatObjs)); pw.flush(); } /** Load objects from XML file. * @param reader * @param map an empty map. It will be filled by processed values and returned back. * @param mainElement main element of the XML * @return a map, where keys are SharedClassObjects and values are values of SCO encoded to String. */ public static Map loadObjects(Reader reader, Map map, String mainElement) throws IOException { try { Parser parser = XMLDataObject.createParser(); HandlerObjects handler = new HandlerObjects(map, mainElement); parser.setDocumentHandler(handler); parser.parse(new InputSource(reader)); } catch (SAXException ex) { throw new org.openide.util.io.FoldingIOException(ex); } return map; } /** */ public static void loadDiffSet(Reader reader, DiffSet diffset) throws IOException { try { Parser parser = XMLDataObject.createParser(); HandlerDiffSet handler = new HandlerDiffSet(diffset); parser.setDocumentHandler(handler); parser.parse(new InputSource(reader)); } catch (SAXException ex) { throw new org.openide.util.io.FoldingIOException(ex); } } /** */ public static void saveDiffSet(Writer writer, DiffSet diffset) throws IOException { // write header PrintWriter pw = new PrintWriter(writer); pw.println(FMT_XML_HEADER); // write diff set start element pw.println("<" + HandlerDiffSet.ELEMENT_DIFF_SET + " clear=\"" + diffset.isClear() + "\" version=\"1.0\">"); // NOI18N // write add Iterator it = diffset.addedItems().iterator(); while (it.hasNext()) { String item = (String) it.next(); pw.print(" <add name=\""); // NOI18N pw.print(encodeToProperXML(item)); pw.print("\" value=\""); // NOI18N pw.print(encodeValue(diffset.addedItem(item))); pw.println("\"/>"); // NOI18N } // write remove it = diffset.removedItems().iterator(); while (it.hasNext()) { String item = (String) it.next(); pw.print(" <remove name=\""); // NOI18N pw.print(encodeToProperXML(item)); pw.println("\"/>"); // NOI18N } // write order pw.print(" <order value=\""); // NOI18N pw.print(encodeStrings(diffset.getOrder())); pw.println("\"/>"); // NOI18N // write diff set end element pw.println("</" + HandlerDiffSet.ELEMENT_DIFF_SET +">"); // NOI18N } }